<p>Because it is easy to extract strings from an application source code or binary, secrets should not be hard-coded. This is particularly true for
applications that are distributed or that are open-source.</p>
<p>In the past, it has led to the following vulnerabilities:</p>
<ul>
  <li> <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-25510">CVE-2022-25510</a> </li>
  <li> <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-42635">CVE-2021-42635</a> </li>
</ul>
<p>Secrets should be stored outside of the source code in a configuration file or a management service for secrets.</p>
<p>This rule detects variables/fields having a name matching a list of words (secret, token, credential, auth, api[_.-]?key) being assigned a
pseudorandom hard-coded value. The pseudorandomness of the hard-coded value is based on its entropy and the probability to be human-readable. The
randomness sensibility can be adjusted if needed. Lower values will detect less random values, raising potentially more false positives.</p>
<h2>Ask Yourself Whether</h2>
<ul>
  <li> The secret allows access to a sensitive component like a database, a file storage, an API, or a service. </li>
  <li> The secret is used in a production environment. </li>
  <li> Application re-distribution is required before updating the secret. </li>
</ul>
<p>There would be a risk if you answered yes to any of those questions.</p>
<h2>Recommended Secure Coding Practices</h2>
<ul>
  <li> Store the secret in a configuration file that is not pushed to the code repository. </li>
  <li> Use your cloud provider’s service for managing secrets. </li>
  <li> If a secret has been disclosed through the source code: revoke it and create a new one. </li>
</ul>
<h2>Sensitive Code Example</h2>
<pre>
private static final String MY_SECRET = "47828a8dd77ee1eb9dde2d5e93cb221ce8c32b37";

public static void main(String[] args) {
  MyClass.callMyService(MY_SECRET);
}
</pre>
<h2>Compliant Solution</h2>
<p>Using <a href="https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/secrets-manager">AWS Secrets Manager</a>:</p>
<pre>
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;

public static void main(String[] args) {
  SecretsManagerClient secretsClient = ...
  MyClass.doSomething(secretsClient, "MY_SERVICE_SECRET");
}

public static void doSomething(SecretsManagerClient secretsClient, String secretName) {
  GetSecretValueRequest valueRequest = GetSecretValueRequest.builder()
    .secretId(secretName)
    .build();

  GetSecretValueResponse valueResponse = secretsClient.getSecretValue(valueRequest);
  String secret = valueResponse.secretString();
  // do something with the secret
  MyClass.callMyService(secret);
}
</pre>
<p>Using <a href="https://docs.microsoft.com/en-us/azure/key-vault/secrets/quick-create-java?tabs=azure-cli">Azure Key Vault Secret</a>:</p>
<pre>
import com.azure.identity.DefaultAzureCredentialBuilder;

import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;

public static void main(String[] args) throws InterruptedException, IllegalArgumentException {
  String keyVaultName = System.getenv("KEY_VAULT_NAME");
  String keyVaultUri = "https://" + keyVaultName + ".vault.azure.net";

  SecretClient secretClient = new SecretClientBuilder()
    .vaultUrl(keyVaultUri)
    .credential(new DefaultAzureCredentialBuilder().build())
    .buildClient();

  MyClass.doSomething(secretClient, "MY_SERVICE_SECRET");
}

public static void doSomething(SecretClient secretClient, String secretName) {
  KeyVaultSecret retrievedSecret = secretClient.getSecret(secretName);
  String secret = retrievedSecret.getValue(),

  // do something with the secret
  MyClass.callMyService(secret);
}
</pre>
<h2>See</h2>
<ul>
  <li> OWASP - <a href="https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/">Top 10 2021 Category A7 - Identification and
  Authentication Failures</a> </li>
  <li> OWASP - <a href="https://owasp.org/www-project-top-ten/2017/A2_2017-Broken_Authentication">Top 10 2017 Category A2 - Broken Authentication</a>
  </li>
  <li> CWE - <a href="https://cwe.mitre.org/data/definitions/798">CWE-798 - Use of Hard-coded Credentials</a> </li>
  <li> MSC - <a href="https://wiki.sei.cmu.edu/confluence/x/OjdGBQ">MSC03-J - Never hard code sensitive information</a> </li>
</ul>

